package net.xconcepts.stockdata.model.analysis.indicator;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import net.xconcepts.stockdata.model.analysis.symbol.Symbol;
import net.xconcepts.stockdata.model.tick.SymbolTick;

/**
 * Statefull indicator which works on a given period of dataa
 * @author Steven
 *
 */
public abstract class PeriodIndicator<T, K> extends Indicator<T, K>{

	private final int mPeriodSize;
	private final Map<Symbol, LinkedList<K>> mHistoricData = new HashMap<Symbol, LinkedList<K>>();
	
	/**
	 * 
	 * @param numTicksInPeriod For example 30-day moving average
	 */
	public PeriodIndicator (Indicator<K, ?> baseIndicator, int numTicksInPeriod) {
		super(baseIndicator);
		if(baseIndicator == null) throw new IllegalArgumentException("Period indicator requires a base indicator");
		mPeriodSize = numTicksInPeriod;
	}
	
	@Override
	protected T processSymbolTick(SymbolTick tick, K baseIndicatorData) {
		LinkedList<K> historicData = mHistoricData.get(tick.getSymbol());
		if(mHistoricData == null) {
			historicData = new LinkedList<K>();
			mHistoricData.put(tick.getSymbol(), historicData);
		}
		
		historicData.add(baseIndicatorData);
		
		if(historicData.size() > mPeriodSize) historicData.remove();
		
		return calculateIndicator(historicData);
	}

	protected abstract T calculateIndicator(LinkedList<K> historicData);
	
	public int getPeriodSize() {
		return mPeriodSize;
	}
}
